package cn.antblog.jvm.gc;

/**
 * @author yangjy
 * @version 1.0
 * @description: 此方法正是最终判定方法，如果子类重写了此方法，那么子类对象在被判定为可回收时，会进行二次确认，也就是执行finalize()方法，
 * 而在此方法中，当前对象是完全有可能重新建立GC Roots的！所以，如果在二次确认后对象不满足可回收的条件，那么此对象不会被回收，巧妙地逃过了垃圾回收的命运。
 * 比如下面这个例子：
 * @date 2022/11/9 17:16
 */
public class FinalizeTest {
    private static Test a;

    public static void main(String[] args) throws InterruptedException {
        a = new Test();
        //这里直接把a赋值为null，这样前面的对象我们不可能再得到了
        a = null;

        //手动申请执行垃圾回收操作（注意只是申请，并不一定会执行，但是一般情况下都会执行）
        System.gc();

        //等垃圾回收一下()
        Thread.sleep(1000);


        //我们来看看a有没有被回收
        System.out.println(a);
    }

    private static class Test {
        @Override
        protected void finalize() throws Throwable {
            //同时，同一个对象的finalize()方法只会有一次调用机会，也就是说，如果我们连续两次这样操作，那么第二次，对象必定被回收：
            System.out.println(this + " 开始了它的救赎之路！");
            a = this;
            //super.finalize();
        }
    }

}
